package restaurant.gui;

import jade.core.AID;

import restaurant.core.Restaurant;
import restaurant.gui.Action.Type;

public class Agent extends AbstractAgent {
	private Restaurant restaurant;
	private AID aid;
	private boolean goalReached = false;
	
	public Square.Type type;
	
	public Agent(int x, int y, AID aid, Square.Type type) {
		super(x, y);

		this.aid = aid;
		this.restaurant = Restaurant.getInstance();
		this.type = type;
	}
	
	@Override
	public void perceives(Perception perception) {
		this.perception = perception;
	}
	
	@Override
	public void update() {
		myBehaviourWithoutObstacle();
	}

	/**
	 * It is the agent behaviour when there are no obstacles
	 */
	private void myBehaviourWithoutObstacle() {
//		System.out.println("MY CELL " + x + "," + y + ": " + perception.floor.get(x, y));
		if(isGoalNode()) {
			currAction = Action.Type.NOOP;
			this.goalReached = true;
		} else {
			currAction = getNextSquare();
		}
	}
	
	/**
	 * 
	 * @return true if the actual position is the same of the goal node
	 */
	private boolean isGoalNode() {
		if(this.restaurant.agentsGoal == null || this.restaurant.agentsGoal.isEmpty())
			return false;
		
		Coordinate tmp = this.restaurant.agentsGoal.get(this.aid);
		if(tmp == null)
			return false;
		
		if(this.x == tmp.x && this.y == tmp.y)
			return true;
		return false;
	}

	/**
	 * 
	 * @return the action to perform at next step
	 */
	public Action.Type getNextSquare() {
		if(this.restaurant.agentsGoal == null || this.restaurant.agentsGoal.isEmpty()) {
			if(this.type == Square.Type.WAITER) {
				if(this.restaurant.agentsScore.get(this.aid) == null)
					this.restaurant.agentsScore.put(this.aid, 0.0);
				double score = this.restaurant.agentsScore.get(this.aid) - 0.01;
				this.restaurant.agentsScore.put(this.aid, score);
			}
			return Type.NOOP;
		}
		
		Coordinate goal = this.restaurant.agentsGoal.get(this.aid);
		if(goal != null) {
			System.out.println(x + " " + y);
			if(goal.x > x) {
				if(this.type == Square.Type.WAITER) {
					if(this.restaurant.agentsScore.get(this.aid) == null)
						this.restaurant.agentsScore.put(this.aid, 0.0);
					double score = this.restaurant.agentsScore.get(this.aid) + 1;
					this.restaurant.agentsScore.put(this.aid, score);
				}
				return Type.SOUTH;
			}
			if(goal.x < x) {
				if(this.type == Square.Type.WAITER) {
					if(this.restaurant.agentsScore.get(this.aid) == null)
						this.restaurant.agentsScore.put(this.aid, 0.0);
					double score = this.restaurant.agentsScore.get(this.aid) + 1;
					this.restaurant.agentsScore.put(this.aid, score);
				}
				return Type.NORTH;
			}
			if(goal.y > y) {
				if(this.type == Square.Type.WAITER) {
					if(this.restaurant.agentsScore.get(this.aid) == null)
						this.restaurant.agentsScore.put(this.aid, 0.0);
					double score = this.restaurant.agentsScore.get(this.aid) + 1;
					this.restaurant.agentsScore.put(this.aid, score);
				}
				return Type.EAST;
			}
			if(goal.y < y) {
				if(this.type == Square.Type.WAITER) {
					if(this.restaurant.agentsScore.get(this.aid) == null)
						this.restaurant.agentsScore.put(this.aid, 0.0);
					double score = this.restaurant.agentsScore.get(this.aid) + 1;
					this.restaurant.agentsScore.put(this.aid, score);
				}
				return Type.WEST;
			}
		}
		
		if(this.type == Square.Type.WAITER) {
			if(this.restaurant.agentsScore.get(this.aid) == null)
				this.restaurant.agentsScore.put(this.aid, 0.0);
			double score = this.restaurant.agentsScore.get(this.aid) - 0.01;
			this.restaurant.agentsScore.put(this.aid, score);
		}
		return Type.NOOP;
	}
	
	public AID getAID() {
		return aid;
	}
	
	public void setAID(AID aid) {
		this.aid = aid;
	}

	public boolean obiettivo() {
		return this.goalReached;
	}
	
	public boolean goalReached() {
		return false;
	}
	
	public void setGoalReached(boolean goalReached) {
		this.goalReached = goalReached;
	}

	@Override
	public void showActions() {
		for(int i = 0; i<actionList.size(); i++)
			System.out.println(actionList.get(i).type);
	}

	@Override
	public restaurant.gui.Action.Type action() {
		actionList.add(new Action(currAction, x, y));
		return currAction;
	}
}